﻿using Coldairarrow.Entity.Backstage.UserData;
using Coldairarrow.Entity.Backstage.Valickets;
using Coldairarrow.Entity.Frontstage.Valickets;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Frontstage.Valickets
{
    public class BS_UserVailTicketBusiness : BaseBusiness<BS_UserVailTicket>, IBS_UserVailTicketBusiness, ITransientDependency
    {
        readonly Operator _operator;
        public BS_UserVailTicketBusiness(IDbAccessor db,Operator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

        public async Task<PageResult<BS_UserVailTicket>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<BS_UserVailTicket>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<BS_UserVailTicket, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<BS_UserVailTicket> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(BS_UserVailTicket data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(BS_UserVailTicket data)
        {
            await UpdateAsync(data);
        }

        /// <summary>
        /// 代金券兑换
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ChangeTicket(ChangeTInput input)
        {
            if (input.Count.HasValue && input.Count > 0)
            {
                var mList = Db.GetIQueryable<BS_UserICPoint>().Where(x => x.UserId.Equals(_operator.UserId)).ToList();
                if (mList.Count > 0)
                {
                    try
                    {
                        int point = (int)mList[0].Point; //用户积分
                        var tmodel = await Db.GetEntityAsync<BS_VailTicket>(input.TicketId);
                        if (!tmodel.IsNullOrEmpty() && tmodel.Ticket_Type == 0)
                        {
                            int tickNum = (int)input.Count;
                            int totalPoint = (int)tmodel.Ticket_ChangePoint * tickNum;

                            if (point >= totalPoint)
                            {
                                point -= totalPoint;

                                #region //用户优惠券插入
                                for (int k = 0; k < tickNum; k++)
                                {
                                    BS_UserVailTicket uModel = new BS_UserVailTicket();
                                    uModel.Id = IdHelper.GetId();
                                    uModel.Deleted = false;
                                    uModel.CreateTime = DateTime.Now;
                                    uModel.CreatorId = _operator.UserId;
                                    uModel.VailTicketId = input.TicketId;
                                    uModel.UserId = _operator.UserId;
                                    uModel.StartTime = DateTime.Now;

                                    #region//代金券信息
                                    uModel.Ticket_Title = tmodel.Ticket_Title;
                                    uModel.Ticket_Amount = tmodel.Ticket_Amount;
                                    uModel.Ticket_BackImg = tmodel.Ticket_BackImg;
                                    uModel.Ticket_Abstract = tmodel.Ticket_Abstract;
                                    uModel.Ticket_KeepOne = tmodel.Ticket_KeepOne;
                                    uModel.Ticket_ChangePoint = tmodel.Ticket_ChangePoint;
                                    uModel.Note = tmodel.Note;
                                    #endregion
                                    if (tmodel.Ticket_EndTime.HasValue)
                                    {
                                        uModel.EndTime = (DateTime)tmodel.Ticket_EndTime;
                                    }
                                    else if (tmodel.Ticket_VailDay.HasValue)
                                    {
                                        uModel.EndTime = uModel.StartTime.AddDays((int)tmodel.Ticket_VailDay);
                                    }
                                    else
                                    {
                                        uModel.EndTime = uModel.StartTime.AddDays(3660);
                                    }
                                    uModel.UseState = 0;

                                    await Db.InsertAsync(uModel);
                                }
                               
                                #endregion

                                #region//用户积分消费记录
                                BS_UserPUseLog log = new BS_UserPUseLog();
                                log.Id = IdHelper.GetId();
                                log.Deleted = false;
                                log.CreateTime = DateTime.Now;
                                log.CreatorId = _operator.UserId;
                                log.UserId = _operator.UserId;
                                log.Type = -1;
                                log.PointNum = -1 * totalPoint;

                                if (tmodel.Ticket_Type == 1)
                                {
                                    log.Purpose = "满" + tmodel.Ticket_UseMoney + "减" + tmodel.Ticket_Amount + "元代金券兑换";
                                }
                                else
                                {
                                    log.Purpose = tmodel.Ticket_Amount + "元代金券兑换";
                                }

                                log.Time = DateTime.Now;
                                await Db.InsertAsync(log);
                                #endregion

                                mList[0].Point = point;
                                await Db.UpdateAsync(mList[0]);
                            }
                            else
                            {
                                throw new BusException("用户积分不足，无法兑换！");
                            }
                        }
                        else
                        {
                            throw new BusException("未查询到此代金券信息，请重试！");
                        }       
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Contains("用户积分不足"))
                        {
                            throw new BusException(ex.Message);
                        }
                        else
                        {
                            throw new BusException("兑换异常，请重试！");
                        }

                    };

                }
                else
                {
                    throw new BusException("用户积分不足，无法兑换！");
                }
            }
            else
            {
                throw new BusException("兑换数量必须大于零，兑换失败！");
            }
        }

        public async Task<object> GetMyTicket(GetTicketInput input)
        {
            List<int> sList = new List<int>();
            if (input.State.HasValue && input.State == 0)
            {
                sList.Add(0);
            }
            else if (input.State.HasValue && input.State == 1)
            {
                sList.Add(1);
                sList.Add(2);
            }
            var theTime = DateTime.Now;
            var list = await (from a in GetIQueryable().Where(x => x.UserId.Equals(_operator.UserId)).WhereIf(input.useMoney.HasValue, x => x.Ticket_Amount < input.useMoney && ((x.Ticket_Type == 1 && x.Ticket_UseMoney <= input.useMoney) || x.Ticket_Type == 0))
                              select new UserVailTicketDTO
                              {
                                  Id = a.Id,
                                  TicketId = a.VailTicketId,
                                  Ticket_Type = a.Ticket_Type,
                                  Ticket_Title = a.Ticket_Title,
                                  Ticket_Amount = a.Ticket_Amount,
                                  Ticket_UseMoney = a.Ticket_UseMoney,
                                  Ticket_ChangePoint = a.Ticket_ChangePoint,
                                  Ticket_BackImg = a.Ticket_BackImg,
                                  Note = a.Note,
                                  Ticket_Abstract = a.Ticket_Abstract,
                                  StartTime = a.StartTime,
                                  EndTime = a.EndTime,
                                  UseState = a.UseState == 1?1:(a.UseState == 0 && a.EndTime > theTime)?0:2
                              }).WhereIf(input.State.HasValue,x=> sList.Contains((int)x.UseState)).ToListAsync();

            int total = GetIQueryable().Where(x => x.UserId.Equals(_operator.UserId)).Count();
            int nCount  =  (from a in GetIQueryable().Where(x => x.UserId.Equals(_operator.UserId))
                            select new UserVailTicketDTO
                            {
                                Id = a.Id,
                                TicketId = a.VailTicketId,
                                Ticket_Title = a.Ticket_Title,
                                Ticket_Amount = a.Ticket_Amount,
                                Ticket_ChangePoint = a.Ticket_ChangePoint,
                                Ticket_BackImg = a.Ticket_BackImg,
                                Note = a.Note,
                                Ticket_Abstract = a.Ticket_Abstract,
                                StartTime = a.StartTime,
                                EndTime = a.EndTime,
                                UseState = a.UseState == 1 ? 1 : (a.UseState == 0 && a.EndTime > theTime) ? 0 : 2
                            }).Where( x => x.UseState == 0).Count();

            object sumData = new { 
                Total = total,
                KSYNum = nCount,
                YSYNum = total-nCount
            };

            object Data = new { 
                SumData = sumData,
                List = list
            };

            return Data;
        }


        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        #endregion

        #region 私有成员

        #endregion
    }
}